package OddMuse;

=head1 NAME

OddMuse::Database::Tagging - Perl Module for OddMuse Tagging

=head1 DESCRIPTION

This module renders tags when found in wikitext, as well as provides a function to
display a "tag cloud".

=cut

$VERSION = ( q$Revision: 38 $ ) =~ /(\d+)/g;
use strict;

=head1 GLOBAL VARIABLES

=over 2

=item * $SearchFreeTextTagUrl

default:     http://technorati.com/tag/

alt:         /?search=tag:

alt:         /?action=collect;search=tag:


=back

=cut

use vars qw($SearchFreeTextTagUrl);    # Import from config file
$SearchFreeTextTagUrl = 'http://technorati.com/tag/' if !$SearchFreeTextTagUrl;

=head1 SYNOPSIS

If you wish to display the Tag Cloud, you will need to insert it into your code
somewhere.  For example, you can stuff it into the bottom of each page by
doing...

 sub PrintMyContent {
     &CoolCloud;
 } 

You can also modify the OddMuse footer to achieve a similar result.

 *OldPrintFooter = *PrintFooter;
 *PrintFooter = *TagCloudPrintFooter;

 sub TagCloudPrintFooter {
     my ( $id, $rev, $comment ) = @_;
     &CoolCloud;
     OldBacklinksPrintFooter( @_ );
 }

=head1 RULES

=over 4

=item * MetaTagsRule

This rule is appended to the OddMuse @Rules array, and renders tag links into
an appopriate tag link based on $SearchFreeTextTagUrl which is defined in the
configuration file for OddMuse.

It searches for [[tag:Something]] in your Wiki text.

=back

=cut

push( @MyRules, \&MetaTagsRule );
sub MetaTagsRule {
    if (    m/\G(\[\[tag:$FreeLinkPattern\]\])/cog
         or m/\G(\[\[tag:$FreeLinkPattern\|([^]|]+)\]\])/cog )
    {

        # [[tag:Free Link]], [[tag:Free Link|alt text]]
        my ( $tag, $text ) = ( $2, $3 );
        return
          $q->a( {  -href  => $SearchFreeTextTagUrl . UrlEncode( $tag ),
                    -class => 'outside tag',
                    -title => T( 'Tag' ),
                    -rel   => 'tag'
                 },
                 $text || $tag
               );
    } ## end if ( m/\G(\[\[tag:$FreeLinkPattern\]\])/cog...
    return undef;
} ## end sub MetaTagsRule

=head1 FUNCTIONS

=over 4

=item * CoolCloud

This function prints out a tag cloud, displayed from most used to least used.

If works by creating a connection to the database store, and parsing throught
the entire index for tags which were collected by the database Building
process.  As matches are found, tags are added to a new hash and a maximum and
minimum tag count for each tag is created.

Later this new hash %count, is looped through for printing in proper html.

This function was heavily influenced by the search-freetext.pl plugin by Alex 
Schroeder

=cut

sub CoolCloud {
    my ( %count, %seen, @tagcount, @tags, $max, $min, $tagcount );
    my $ondisk = OddMuse::Database->new();    # Connect to disk store

    while ( my ( $source, $hashes ) = each %{ $ondisk } ) {
        while ( my ( $key, $value ) = each %$hashes ) {
            if ( $key =~ /^tag/ ) {
                foreach my $tag ( @{ $value } ) {
                    $tag =~ s/\ //g;
                    $max = $count{ $tag } if $count{ $tag } > $max;
                    $min = $count{ $tag } if not $min or $count{ $tag } < $min;
                    $count{ $tag }
                      ++;    # Store Data in new array, with a count of tags
                    push( @tagcount, $tag )
                      unless ( $seen{ $tag }++ );    # For comma dropping
                } ## end foreach my $tag ( @{ $value...
            } ## end if ( $key =~ /^tag/ )
        } ## end while ( my ( $key, $value...
    } ## end while ( my ( $source, $hashes...

    my $numtags = @tagcount;
    ( %seen, @tagcount ) = undef;
    my $tagcount = 1;                                # Used to drop last comma

    foreach my $key ( sort { $count{ $b } <=> $count{ $a } } keys %count ) {
        print $q->a( {  -href  => "$SearchFreeTextTagUrl" . UrlEncode( $key ),
                        -title => "Pages tagged as $key: " . $count{ $key },
                        -style => 'font-size: '
                          . int( 80 + 120 * ( $count{ $key } - $min ) /
                                   ( $max - $min )
                               )
                          . "%;\""
                     },
                     $key
                   );
        print ", " if ( $tagcount++ < $numtags );
    } ## end foreach my $key ( sort { $count...

    if ( @tags eq '' ) {
        print
          "<p>No tags defined, database unavailable, or it's corrupted.  Please regenerate MetaDatabase</p>";
    }
} ## end sub CoolCloud

1;

__END__

=back

=head1 CSS

=over 4

=item * a.tag

Used when a tag is found in the wiki text.

The tagcloud is rendered manually via the style css property.

=back

=head1 BUGS AND LIMITATIONS

No bugs have been reported.

Please report any bugs or feature requests to C<cmauch@gmail.com>

=head1 AUTHOR

Charles Mauch <cmauch@gmail.com>

=head1 LICENSE

Copyright (c) 2006 Charles Mauch

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

=head1 SEE ALSO

perl(1).

=cut

# $Id: Tagging.pm 38 2006-10-01 04:06:35Z cmauch $
